package AppConfig

import (
	"encoding/json"
	"io/ioutil"
	"os"
)

// Config  定义配置项基类
type Config struct {
	Host      string `json:"host"`
	Httpport  string `json:"httpport"`
	Env       string `json:"env"`
	MongoDB   string `json:"mongoDB"` //数据库名称
	MongoHost string `json:"mongoHost"`
	MongoPort string `json:"mongoPort"`
	MongoUser string `json:"mongoUser"`
	MongoPass string `json:"mongoPass"`
}

// AppConf  app配置项,从同级config.json文件读取
type AppConf struct {
	Config
	Dev  Config `json:"dev"`
	Prod Config `json:"prod"`
}

// SetupInitValues 设置缺失的字段的值
func (c *AppConf) setupInitValues() {
	c.Host = "http://119.23.239.201"
	c.Httpport = "8083"
	c.Env = "prod"

}

var (
	//Conf 配置项结构体
	Conf AppConf

	//ExportDir 导出目录
	ExportDir = "./export"
)

func init() {
	// //读取配置
	// Conf = loadAppConfig()

	// //容错 , 默认生产环境
	// if Conf.Env == "" {
	// 	Conf.Env = "prod"
	// }

}

// app配置项,从同级config.json文件读取
func LoadAppConfig(confPath string) AppConf {
	conf := AppConf{}
	conf.setupInitValues()

	file, err := os.Open(confPath)
	defer file.Close()
	if err != nil {
		return conf
	}

	fd, err := ioutil.ReadAll(file)
	// confStr := string(fd)
	// println("配置内容:",confStr)

	// //json解析到结构体里面
	// err = json.Unmarshal([]byte(confStr), &conf)

	//1.先转成map
	var mapResult map[string]interface{}
	merr := json.Unmarshal(fd, &mapResult)

	if merr == nil {
		//2. 替换值
		rmap := getReplaceMap(&mapResult)
		for k, v := range rmap {
			mapResult[k] = v
		}

		//3 转回json,再转回struct
		jsonStr, err := json.Marshal(mapResult)
		if err == nil {
			merr = json.Unmarshal([]byte(jsonStr), &conf)

		}
	}

	return conf
}

// 获取需要替换的配置项
func getReplaceMap(mapResult *map[string]interface{}) map[string]interface{} {

	var mapR map[string]interface{}
	if env, ok := (*mapResult)["env"]; ok {
		if env == "dev" {

			if dev, ok := (*mapResult)["dev"]; ok {
				if m, ok := dev.(map[string]interface{}); ok {
					mapR = m
				}
			}

		} else if env == "prod" {

			if prod, ok := (*mapResult)["prod"]; ok {
				//类型断言
				if m, ok := prod.(map[string]interface{}); ok {
					mapR = m
				}
			}
		}
	}

	return mapR
}
